<template>
	<div class="app-columns-container flexrbc">
		<div class="app-left-container flexcec">
			<div class="model-container">
				<div id="modelZ-container">
				</div>
			</div>
			<div class="app-columns-bottom">
				<faultList :data='dataList' :type="1"></faultList>
			</div>
		</div>

		<div class="app-right-container flexcec">
			<div class="model-container">
				<div id="modelF-container">
				</div>
			</div>
			<div class="app-columns-bottom">
				<faultList :data='dataList' :type="2"></faultList>
			</div>
		</div>
	</div>
</template>


<script>
	import api from "@/api/http.js";
	// 模型开始
	import * as THREE from 'three'
	import {
		GLTFLoader
	} from 'three/examples/jsm/loaders/GLTFLoader';
	import {
		OrbitControls
	} from 'three/examples/jsm/controls/OrbitControls';
	import {
		EffectComposer
	} from "three/examples/jsm/postprocessing/EffectComposer"
	import {
		RenderPass
	} from "three/examples/jsm/postprocessing/RenderPass"
	import {
		OutlinePass
	} from "three/examples/jsm/postprocessing/OutlinePass"
	import {
		GammaCorrectionShader
	} from 'three/examples/jsm/shaders/GammaCorrectionShader';
	import {
		ShaderPass
	} from "three/examples/jsm/postprocessing/ShaderPass"
	import {
		FXAAShader
	} from "three/examples/jsm/shaders/FXAAShader";
	import faultList from './components/faultList.vue'
	// 模型结束
	import {
		Loading
	} from 'element-ui';
	const configUrl = window.IP
	export default {
		name: "CalendarTraffic",
		data() {
			return {  
				zLoadingInstance: null,
				fLoadingInstance: null,
				// 模型开始
				zCamera: null, //相机
				fCamera: null, //相机
				zScene: null, //场景
				fScene: null, //场景
				zRenderer: null, //渲染器
				fRenderer: null, //渲染器
				zContainer: null, //容器
				fContainer: null, //容器
				zControls: null, //控制器
				fControls: null, //控制器
				zComposer: null,
				fComposer: null,
				zRenderPass: null,
				fRenderPass: null,
				zAnimateId: null,
				fAnimateId: null,
				// 模型结束  
				scaleNum: 1, 
				modelUrl: '',
				hiddenModelPoints: [],
				animationIndex: '',
				faultColor: '',
				dataList: [{
						name: '传感器0',
						id: 0
					}, {
						name: '传感器1',
						id: 1
					},
					{
						name: '传感器2',
						id: 2
					},
					{
						name: '传感器3',
						id: 3
					},
					{
						name: '传感器4',
						id: 4
					},
					{
						name: '传感器5',
						id: 5
					},
					{
						name: '传感器6',
						id: 6
					},
					{
						name: '传感器7',
						id: 7
					}

				],

			}
		},
		components: {
			faultList
		},
		computed: {
			resourUrl() {
				return configUrl.resourUrl;
			},
		},
		beforeDestroy() {
			this.zScene = null
			this.zCamera = null
			this.zRenderer = null
			this.zControls = null;
			this.zContainer = null;
			this.zComposer = null;
			this.zRenderPass = null;
			this.zAnimateId = null;

			this.fScene = null
			this.fCamera = null
			this.fRenderer = null
			this.fControls = null;
			this.fContainer = null;
			this.fComposer = null;
			this.fRenderPass = null;
			this.fAnimateId = null;
			if (this.zLoadingInstance) {
				this.zLoadingInstance.close()
			};
			if (this.fLoadingInstance) {
				this.fLoadingInstance.close()
			}
		},
		created() {},
		mounted() {
			this.getModel();
			this.$nextTick(() => {
				window.addEventListener('resize', () => { 
					// 设置摄像机视锥体的长宽比（覆盖创建相机时的长宽比）
					if (this.zCamera && this.zContainer) {
						this.zCamera.aspect = this.zContainer.clientWidth / this.zContainer.clientHeight;
						// 更新摄像机投影矩阵。在任何参数被改变以后必须被调用。
						this.zCamera.updateProjectionMatrix();
					}
					if (this.zRenderer && this.zContainer) {
						// 设置渲染区尺寸
						this.zRenderer.setSize(this.zContainer.clientWidth, this.zContainer.clientHeight);
						// 设置设备像素比
						this.zRenderer.setPixelRatio(window.devicePixelRatio);
					}
					if (this.fCamera && this.fContainer) {
						this.fCamera.aspect = this.fContainer.clientWidth / this.fContainer.clientHeight;
						// 更新摄像机投影矩阵。在任何参数被改变以后必须被调用。
						this.fCamera.updateProjectionMatrix();
					}
					if (this.fRenderer && this.fContainer) {
						// 设置渲染区尺寸
						this.fRenderer.setSize(this.fContainer.clientWidth, this.fContainer.clientHeight);
						// 设置设备像素比
						this.fRenderer.setPixelRatio(window.devicePixelRatio);
					}
				})
			});



		},
		methods: {

			changeAnimation(i) {
				this.animationIndex = i;
			},
			clearModel() {
				if (this.zScene !== null && this.zScene.children.length > 3) {
					this.zScene.children.pop()
					// 必须要清空当前div下的canvas不然canvas会继续叠加
					this.zContainer = document.getElementById('modelZ-container')
					if (this.zContainer !== null) {
						this.zContainer.removeChild(this.zContainer.childNodes[0])
					}
				};
				if (this.fScene !== null && this.fScene.children.length > 3) {
					this.fScene.children.pop()
					// 必须要清空当前div下的canvas不然canvas会继续叠加
					this.fContainer = document.getElementById('modelF-container')
					if (this.fContainer !== null) {
						this.fContainer.removeChild(this.fContainer.childNodes[0])
					}
				}
			},
			getModel() {

				this.zLoadingInstance = Loading.service({
					text: '加载中',
					target: '#modelZ-container',
					background: 'rgba(0,0,0,0.2)'
				});
				this.fLoadingInstance = Loading.service({
					text: '加载中',
					target: '#modelF-container',
					background: 'rgba(0,0,0,0.2)'
				});
				this.modelUrl = "/document/fafaf6c3c8c94f8c93ad3871e1488cbf.glb";
				 if (this.modelUrl) {
					this.clearModel();
					this.init();
					this.animateZ();
					this.animateF();
				}
				this.hiddenModelPoints = [{
						name: 'device_F1',
						type: '几何模态'
					},
					{
						name: 'device_F3',
						type: '力学模态'
					},
					{
						name: 'device_F4',
						type: '光学模态'
					},
					{
						name: 'device_F5',
						type: '电学模态'
					},
					{
						name: 'device_F6',
						type: '热学模态'
					}
				]
				// let params = {
				// 	departmentId: ''
				// }
				// api.departHiddenModel(params).then(res => {
				// 	this.loadingInstance = Loading.service({
				// 		text: '加载中',
				// 		target: '#model-container',
				// 		background: 'rgba(0,0,0,0.2)'
				// 	});
				// 	if (res.data.code == 200) {
				// 		this.modelUrl = res.data.data.hiddenModel.url
				// 		if (this.modelUrl) {
				// 			// 模型开
				// 			this.clearModel();
				// 			this.init();
				// 			this.animate();
				// 			// 模型结束
				// 		}
				// 		this.hiddenModelPoints = (res.data.data.hiddenModel && res.data.data.hiddenModel
				// 			.hiddenModelPoints) ? res.data.data.hiddenModel.hiddenModelPoints : [];

				// 	}
				// })
			},
			// 模型开始
			//创建相机
			initCamera() {
				this.zCamera = new THREE.PerspectiveCamera(45, this.zContainer.clientWidth / this.zContainer
					.clientHeight,
					0.1, 10000)
				this.zCamera.position.set(43, 11, 22); //相机位置

				this.fCamera = new THREE.PerspectiveCamera(45, this.fContainer.clientWidth / this.fContainer
					.clientHeight,
					0.1, 10000)
				this.fCamera.position.set(43, 11, 22); //相机位置
			},
			//创建场景
			initScene() {
				this.zScene = new THREE.Scene();
				this.zScene.add(this.zCamera);

				this.fScene = new THREE.Scene();
				this.fScene.add(this.fCamera)
			},
			//光源
			initZLight() {
				//平行光,沿着特定方向发射的光
				const directionalLight1 = new THREE.DirectionalLight("#ffffff", 1);
				directionalLight1.position.set(1, 1, 1);
				this.zScene.add(directionalLight1);
				const directionalLight2 = new THREE.DirectionalLight("#ffffff", 1);
				directionalLight2.position.set(-1, 0.5, -1);
				this.zScene.add(directionalLight2);
				const directionalLight3 = new THREE.DirectionalLight("#ffffff", 1);
				directionalLight3.position.set(-23, 1, 27);
				this.zScene.add(directionalLight3);
				const directionalLight4 = new THREE.DirectionalLight("#ffffff", 1);
				directionalLight4.position.set(24, 1, -24);
				this.zScene.add(directionalLight4);
				// 添加点光源
				// let ambientLight = new THREE.AmbientLight(0xDFDFDF, 0.7);
				// this.zScene.add(ambientLight);
			},
			initFLight() {
				//平行光,沿着特定方向发射的光
				const directionalLight1 = new THREE.DirectionalLight("#ffffff", 1);
				directionalLight1.position.set(1, 1, 1);
				this.fScene.add(directionalLight1);
				const directionalLight2 = new THREE.DirectionalLight("#ffffff", 1);
				directionalLight2.position.set(-1, 0.5, -1);
				this.fScene.add(directionalLight2);
				const directionalLight3 = new THREE.DirectionalLight("#ffffff", 1);
				directionalLight3.position.set(-23, 1, 27);
				this.fScene.add(directionalLight3);
				const directionalLight4 = new THREE.DirectionalLight("#ffffff", 1);
				directionalLight4.position.set(24, 1, -24);
				this.fScene.add(directionalLight4);
				// 添加点光源
				// let ambientLight = new THREE.AmbientLight(0xDFDFDF, 0.7);
				// this.fScene.add(ambientLight);
			},
			//渲染器
			initZRenderer() {
				this.zContainer = document.getElementById('modelZ-container');
				this.zRenderer = new THREE.WebGLRenderer({
					antialias: true,
					alpha: true
				});
				// 设置 canvas 元素的样式，包括背景颜色和透明度
				this.zRenderer.domElement.style.backgroundColor = 'rgba(1,0, 66, 0.5)';
				this.zRenderer.setPixelRatio(this.zContainer.devicePixelRatio);
				this.zRenderer.setSize(this.zContainer.clientWidth, this.zContainer.clientHeight);
				this.zContainer.appendChild(this.zRenderer.domElement);
			},
			initFRenderer() {
				this.fContainer = document.getElementById('modelF-container');
				this.fRenderer = new THREE.WebGLRenderer({
					antialias: true,
					alpha: true
				});
				// 设置 canvas 元素的样式，包括背景颜色和透明度
				this.fRenderer.domElement.style.backgroundColor = 'rgba(1,0, 66, 0.5)';
				this.fRenderer.setPixelRatio(this.fContainer.devicePixelRatio);
				this.fRenderer.setSize(this.fContainer.clientWidth, this.fContainer.clientHeight);
				this.fContainer.appendChild(this.fRenderer.domElement);
			},
			//视图控制器
			initControls() {
				this.zControls = new OrbitControls(this.zCamera, this.zRenderer.domElement);
				//上下翻转的最大角度
				this.zControls.maxPolarAngle = 1.5;
				//上下翻转的最小角度
				this.zControls.minPolarAngle = 0.3;
				//是否允许缩放
				this.zControls.enableZoom = true;
				//控制是否带有惯性
				this.zControls.enableDamping = true
				// 设置摄像机距离目标点的最小和最大距离。这可以限制用户缩放的范围。 
				this.zControls.minDistance = 1;
				this.zControls.maxDistance = 100;

				this.fControls = new OrbitControls(this.fCamera, this.fRenderer.domElement);
				//上下翻转的最大角度
				this.fControls.maxPolarAngle = 1.5;
				//上下翻转的最小角度
				this.fControls.minPolarAngle = 0.3;
				//是否允许缩放
				this.fControls.enableZoom = true;
				//控制是否带有惯性
				this.fControls.enableDamping = true
				// 设置摄像机距离目标点的最小和最大距离。这可以限制用户缩放的范围。 
				this.fControls.minDistance = 1;
				this.fControls.maxDistance = 100;

			},
			//加载设备模型
			initZGLTF() {
				let that = this
				if (this.modelUrl) {
					function onProgress(xhr) {
						if (xhr.lengthComputable) {
							const percentComplete = xhr.loaded / xhr.total * 100;
						}
					}

					function onError() {}
					//导入模型
					new GLTFLoader().load(this.resourUrl + this.modelUrl, function(object) {
						// console.log(object, 'GLTFLoader---object');
						// 模型缩放开始 
						//显示模型的时候自动计算模型缩放比例
						//计算和世界轴对齐的一个对象 Object3D （含其子对象）的包围盒
						that.zLoadingInstance.close();
						let arr = [];
						var cBox = new THREE.Box3().setFromObject(object.scene);
						let heightc = cBox.max.y - cBox.min.y;
						if (that.zCamera) {
							var dist = heightc / (2 * Math.tan(that.zCamera.fov * Math.PI / 360));
							that.scaleNum = 10 / dist
						};

						object.scene.scale.set(that.scaleNum, that.scaleNum, that.scaleNum); //设置模型比例尺寸
						// 模型缩放结束
						object.scene.position.x = 0;
						object.scene.position.z = 0;
						//给模型内的Mesh集合加到全局
						object.scene.children.forEach(child => {
							// console.log(child,'child---1')
							if (child.name.indexOf('device') != -1) {
								arr.push(child);
							}
						});
						that.outlineZObj(arr);
						if (that.zScene) {
							that.zScene.add(object.scene);
						};
					}, onProgress, onError);
				}
			},
			initFGLTF() {
				let that = this
				if (this.modelUrl) {
					function onProgress(xhr) {
						if (xhr.lengthComputable) {
							const percentComplete = xhr.loaded / xhr.total * 100;
						}
					}

					function onError() {}
					//导入模型
					new GLTFLoader().load(this.resourUrl + this.modelUrl, function(object) {
						// console.log(object, 'GLTFLoader---object');
						// 模型缩放开始 
						//显示模型的时候自动计算模型缩放比例
						//计算和世界轴对齐的一个对象 Object3D （含其子对象）的包围盒
						that.fLoadingInstance.close();
						let arr = [];
						var cBox = new THREE.Box3().setFromObject(object.scene);
						let heightc = cBox.max.y - cBox.min.y;
						if (that.fCamera) {
							var dist = heightc / (2 * Math.tan(that.fCamera.fov * Math.PI / 360));
							that.scaleNum = 10 / dist
						}
						object.scene.scale.set(that.scaleNum, that.scaleNum, that.scaleNum); //设置模型比例尺寸
						// 模型缩放结束
						object.scene.position.x = 0;
						object.scene.position.z = 0;
						//给模型内的Mesh集合加到全局
						object.scene.children.forEach(child => {
							// console.log(child,'child---1')
							if (child.name.indexOf('device') != -1) {
								arr.push(child);
							}
						});
						that.outlineFObj(arr);
						if (that.fScene) {
							that.fScene.add(object.scene);
						};
					}, onProgress, onError);
				}
			},
			animateZ() {
				if (this.zRenderer) {
					this.zRenderer.render(this.zScene, this.zCamera);
				}
				this.zAnimateId = requestAnimationFrame(this.animateZ);

				if (this.zComposer) {
					this.zComposer.render()
				};

			},
			animateF() {
				if (this.fRenderer) {
					this.fRenderer.render(this.fScene, this.fCamera);
				}
				this.fAnimateId = requestAnimationFrame(this.animateF);

				if (this.fComposer) {
					this.fComposer.render()
				}

			},
			init() {
				this.initZRenderer();
				this.initFRenderer()
				this.initCamera()
				this.initScene();
				this.initZLight();
				this.initFLight()
				this.initZGLTF();
				this.initFGLTF();
				this.initControls()
			},
			//高亮显示模型（呼吸灯）
			outlineZObj(selectedObjects) {
				if (this.zRenderer) {
					this.zComposer = new EffectComposer(this.zRenderer)
					// // 新建一个场景通道  为了覆盖到原来的场景上
					this.zRenderPass = new RenderPass(this.zScene, this.zCamera)
					this.zComposer.addPass(this.zRenderPass);
					for (let i = 0; i < selectedObjects.length; i++) {
						// 物体边缘发光通道
						let outlinePass = new OutlinePass(new THREE.Vector2(window.innerWidth, window.innerHeight),
							this.zScene,
							this.zCamera);
						this.zComposer.addPass(outlinePass);
						outlinePass.selectedObjects = [selectedObjects[i]];
						outlinePass.selectedObjects = [selectedObjects[i]];
						outlinePass.edgeStrength = 4.0 // 边框的亮度
						outlinePass.edgeGlow = 1 // 光晕[0,1]
						outlinePass.usePatternTexture = false // 是否使用父级的材质
						outlinePass.edgeThickness = 2 // 边框宽度
						outlinePass.downSampleRatio = 1 // 边框弯曲度
						outlinePass.pulsePeriod = 10 // 呼吸闪烁的速度
						// 根据条件判断设置呼吸灯颜色
						this.setFaultColor(selectedObjects[i], outlinePass);
						outlinePass.hiddenEdgeColor = new THREE.Color(0, 0, 0) // 呼吸消失的颜色
						outlinePass.clear = true
					}
					const gammaPass = new ShaderPass(GammaCorrectionShader);
					this.zComposer.addPass(gammaPass);
				};
			},
			outlineFObj(selectedObjects) {
				if (this.fRenderer) {
					this.fComposer = new EffectComposer(this.fRenderer)
					// // 新建一个场景通道  为了覆盖到原来的场景上
					this.fRenderPass = new RenderPass(this.fScene, this.fCamera)
					this.fComposer.addPass(this.fRenderPass);
					for (let i = 0; i < selectedObjects.length; i++) {
						// 物体边缘发光通道
						let outlinePass = new OutlinePass(new THREE.Vector2(window.innerWidth, window.innerHeight),
							this.fScene,
							this.fCamera);
						this.fComposer.addPass(outlinePass);
						outlinePass.selectedObjects = [selectedObjects[i]];
						outlinePass.edgeStrength = 4.0 // 边框的亮度
						outlinePass.edgeGlow = 1 // 光晕[0,1]
						outlinePass.usePatternTexture = false // 是否使用父级的材质
						outlinePass.edgeThickness = 2 // 边框宽度
						outlinePass.downSampleRatio = 1 // 边框弯曲度
						outlinePass.pulsePeriod = 10 // 呼吸闪烁的速度
						// 根据条件判断设置呼吸灯颜色
						this.setFaultColor(selectedObjects[i], outlinePass);
						outlinePass.hiddenEdgeColor = new THREE.Color(0, 0, 0) // 呼吸消失的颜色
						outlinePass.clear = true
					}
					const gammaPass = new ShaderPass(GammaCorrectionShader);
					this.fComposer.addPass(gammaPass);
				}
				// this.animate();	  
			},
			setFaultColor(selectedObjects, outlinePass) {
				console.log(selectedObjects.name, "selectedObjects.name");
				if (selectedObjects.name === 'device_F1') {
					this.faultColor = 0xFF0000; // 故障颜色
				} else if (selectedObjects.name === 'device_F3') {
					this.faultColor = 0x00FF00; // 风险等级1级绿色
				} else if (selectedObjects.name === 'device_F4') {
					this.faultColor = 0xFFFF00; // 风险等级2级黄色
				} else if (selectedObjects.name === 'device_F5') {
					this.faultColor = 0xFFAA00; // 风险等级3级橙色
				} else if (selectedObjects.name === 'device_F6') {
					this.faultColor = 0xaa5500; // 风险等级4级棕色
				}
				// 设置 OutlinePass 的可见边缘颜色
				outlinePass.visibleEdgeColor.set(this.faultColor);
			},
			// 模型结束    
		}
	};
</script>

<style lang="scss" scoped>
	@import "@/styles/variables.scss";

	.app-right-container {
		background: rgba(0, 0, 0, 0);
		overflow: hidden;
	}


	.model-container {
		width: 100%;
		height: 55%;
		position: relative;
	}

	#modelZ-container,
	#modelF-container {
		width: 100%;
		height: 100%;
		position: absolute;
		top: 0;
		left: 0;
	}

	#modelZ-container canvas,
	#modelF-container canvas {
		width: 100% !important;
	}

	.app-left-container {
		height: 100%;
		overflow: hidden;
		background: rgba(0, 0, 0, 0);
		width: calc(50% - 4px);
	}

	.app-right-container {
		height: 100%;
		overflow: hidden;
		background: rgba(0, 0, 0, 0);
		width: calc(50% - 4px);
	}
</style>